
package cz.czu.pef.DataModelling.dao.impl;

import java.util.*;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.hibernate.*;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import cz.czu.pef.DataModelling.dao.DataModellingDao;
import cz.czu.pef.DataModelling.utils.Constants;

@Repository(value="dataModellingDao")
@Transactional
@Configurable
public class DataModellingDaoImpl implements DataModellingDao
{

	private static final Logger logger = Logger.getLogger(DataModellingDaoImpl.class.getName());
	
	public DataModellingDaoImpl()
	{
	}

	@PersistenceContext
	private EntityManager entityManager;

	public void setEntityManager(EntityManager entityManager)
	{
		this.entityManager = entityManager;
	}
	
	public EntityManager getEntityManager()
	{
		return this.entityManager;
	}
	
	private Session getHibernateSession()
	{
		// http://stackoverflow.com/questions/4148231/how-can-i-get-the-session-object-if-i-have-the-entitymanager
		//org.hibernate.Session session = (Session) entityManager.getDelegate(); // JPA 1.0 spec
		//org.hibernate.Session session = (Session) entityManager.unwrap(Session.class); // JPA 2.0 spec
		return entityManager.unwrap(Session.class); // JPA 2.0 spec style
	}

	/**
	 * Create HQL query for usage by Daos (mainly mapping arguments etc...)
	 *
	 * @param hql
	 * @return Query object suitable for HQL queries
	 */
	protected Query createHqlQuery(final String hql)
	{
		if (logger.isLoggable(Level.INFO))
		{
			logger.info("createHqlQuery - going to create hql query: " + hql);
		}
		return getHibernateSession().createQuery(hql);
	}

	/**
	 * Create SQL query for usage by Daos (mainly mapping arguments etc...)
	 *
	 * @param sql
	 * @return Query object suitable for SQL queries
	 */
	protected SQLQuery createSqlQuery(final String sql)
	{
		if (logger.isLoggable(Level.INFO))
		{
			logger.info("createSqlQuery - going to create sql query: " + sql);
		}
		return getHibernateSession().createSQLQuery(sql);
	}

	/**
	 * Executes HQL or SQL query
	 *
	 * @param query
	 * @return List of entities, or arrays, as defined by HQL
	 */
	protected Object executeQuery(final Query query)
	{
		if (logger.isLoggable(Level.INFO))
		{
			logger.info("executeHql - executing HQL: " + query.getQueryString());
		}
		return query.list();
	}



	@SuppressWarnings("unchecked")
	public List<Object[]> getAllMissingTrainings()
	{
		return createHqlQuery(Constants.missingTrainingsHqlSelect).list();
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> getAllMissingMedicalExaminations()
	{
		return createHqlQuery(Constants.missingMedicalExaminationsHqlSelect).list();
	}
}
